package com.lsmo.android.carfans.app.widget;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.RejectedExecutionException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;

import com.lsmo.android.carfans.Global;
import com.lsmo.android.util.ImageCache;

/**
 * 图片管理类
 * @author SYX
 */
public class RemoteImageView extends ImageView{

	private static int MAX_FAILURES = 3;
	private static String TAG = "RemoteImageView";
	private String mCurrentlyGrabbedUrl;
	private Integer mDefaultImage;
	private int mFailure;
	private GridView mGridView;
	private ListView mListView;
	private int mPosition;
	private String mUrl;
	  
	public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public RemoteImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public RemoteImageView(Context context) {
		super(context);
		init();
	}
	
    /**
	 * Sharable code between constructors
	 */
	private void init(){
	}
	
	private void loadDefaultImage(){
		if (mDefaultImage != null)
	    {
			setImageResource(mDefaultImage);
	    }
	}
	
   public void setDefaultImage(Integer resid)
   {
       mDefaultImage = resid;
   }	
	
	public void setImageUrl(String paramString){
		if ((mListView == null) && (mCurrentlyGrabbedUrl != null) 
				&& (mCurrentlyGrabbedUrl.equals(paramString))){
			return;
		}
		if ((mUrl != null) && (mUrl.equals(paramString))){
			 mFailure++;
			int j = mFailure;
			int k = MAX_FAILURES;
			if(j > k){
				String str1 = "TAG";
				String str2 = "Failed to download " + paramString + ", falling back to default image";
				int m = Log.e(str1,str2);
				loadDefaultImage();
				return;
			}
		}
		else {
			mUrl = paramString;
	        mFailure = 0;
		}
		ImageCache localImageCache = Global.getInstance().getImageCache();
		if(localImageCache.isCached(paramString)){
			this.setImageBitmap(localImageCache.get(paramString));
		} else {
			try {
				DownloadTask localDownloadTask = new DownloadTask();
		        String[] arrayOfString = new String[1];
		        arrayOfString[0] = paramString;
		        localDownloadTask.execute(arrayOfString);
			} 
			catch (RejectedExecutionException localRejectedExecutionException) {
				localRejectedExecutionException.printStackTrace();
			}
		}
	}
	
	public void setImageUrl(String url, int position, GridView paramGridView)
	{
	    mPosition = position;
	    mGridView = paramGridView;
	    setImageUrl(url);
	}
	
	public void setImageUrl(String url, int position, ListView listView)
	{
	    mPosition = position;
	    mListView = listView;
	    setImageUrl(url);
	}

	public void setImageUrl2Drawable(String paramString){
		if ((mListView == null) && (mCurrentlyGrabbedUrl != null) 
				&& (mCurrentlyGrabbedUrl.equals(paramString))){
			return ;
		}
    	if ((mUrl != null) && (mUrl.equals(paramString))){
    		mFailure++;
			if(mFailure > MAX_FAILURES){
				Log.e(Global.TAG, "Failed to download "+paramString+", falling back to default image");
				loadDefaultImage();
				return;
			}
    	} else {
    		mUrl = paramString;
            mFailure = 0;
    	}
    	ImageCache localImageCache = Global.getInstance().getImageCache();
    	if (localImageCache.isCached(paramString)){
    		Bitmap localBitmap = (Bitmap)localImageCache.get(paramString);
            BitmapDrawable localBitmapDrawable = new BitmapDrawable(localBitmap);
            this.setBackgroundDrawable(localBitmapDrawable);
    	} else {
    		try {
	    		DownloadTask localDownloadTask = new DownloadTask();
	            String[] arrayOfString = new String[1];
	            arrayOfString[0] = paramString;
	            localDownloadTask.execute(arrayOfString);
			} catch (RejectedExecutionException localRejectedExecutionException) {
				localRejectedExecutionException.printStackTrace();
			}
    	}
	}
	
	public void setImageUrlbyGrid(String paramString){
		if ((mGridView == null) && (mCurrentlyGrabbedUrl != null) 
				&& (mCurrentlyGrabbedUrl.equals(paramString))){
			return ;
		}
    	if ((mUrl != null) && (mUrl.equals(paramString))){
    		mFailure++;
			if(mFailure > MAX_FAILURES){
				Log.e(Global.TAG, "Failed to download "+paramString+", falling back to default image");
				loadDefaultImage();
				return;
			}
    	}
    	else {
    		mUrl = paramString;
            mFailure = 0;
    	}
    	ImageCache localImageCache = Global.getInstance().getImageCache();
    	if (localImageCache.isCached(paramString)){
            this.setImageBitmap(localImageCache.get(paramString));
    	} else {
    		try
            {
              DownloadTask localDownloadTask = new DownloadTask();
              String[] arrayOfString = new String[1];
              arrayOfString[0] = paramString;
              localDownloadTask.execute(arrayOfString);
            }
            catch (RejectedExecutionException localRejectedExecutionException)
            {
            	localRejectedExecutionException.printStackTrace();
            }
    	}
	}
	 
	/**
	 * 异步线程
	 * @author SYX
	 *
	 */
	class DownloadTask extends AsyncTask<String, Void, String>{
	//后面尖括号内分别是参数（例子里是线程休息时间），进度(publishProgress用到)，返回值 类型  
		private String mTaskUrl;

	    DownloadTask()
	    {
	    	
	    }

	    //该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作，如在界面上显示一个进度条，或者一些控件的实例化，这个方法可以不用实现。
	    @Override
		protected void onPreExecute() {
	    	//第一个执行方法 
			super.onPreExecute();
			loadDefaultImage();
		}
	    //该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法，子类必须实现。
		@Override
		protected String doInBackground(String... paramString) {
			//第二个执行方法,onPreExecute()执行完后执行 
			mTaskUrl = paramString[0];
			InputStream stream = null;
			URL imageUrl;
			Bitmap bmp = null;

			try {
				imageUrl = new URL(mTaskUrl);
				try {
					stream = imageUrl.openStream();
					bmp = BitmapFactory.decodeStream(stream);
					try {
						if(bmp != null){
							Global.getInstance().getImageCache().put(mTaskUrl, bmp);
							Log.d(Global.TAG, "Image cached "+mTaskUrl);
						} else {
							Log.w(Global.TAG, "Failed to cache "+mTaskUrl);
						}
					} catch (NullPointerException e) {
						Log.w(Global.TAG, "Failed to cache "+mTaskUrl);
					}
				} catch (IOException e) {
					Log.w(Global.TAG, "Couldn't load bitmap from url: " + mTaskUrl);
				} finally {
					try {
						if(stream != null){
							stream.close();
						}
					} catch (IOException e) {}
				}

			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
			return mTaskUrl;
		}
		//在publishProgress方法被调用后，UI 线程将调用这个方法从而在界面上展示任务的进展情况，例如通过一个进度条进行展示。
		@Override
		protected void onProgressUpdate(Void... values) {
			super.onProgressUpdate(values);
		}
		
		//在doInBackground 执行完成后，onPostExecute 方法将被UI 线程调用，后台的计算结果将通过该方法传递到UI 线程，并且在界面上展示给用户.
		@Override
		protected void onPostExecute(String paramString) {
			//这里的paramString就是上面doInBackground执行后的返回值
			super.onPostExecute(paramString);
			String str1 = mTaskUrl;
		    String str2 = mUrl;
		    if (!str1.equals(str2))
		    	return;
		    	Bitmap localBitmap = (Bitmap)Global.getInstance().getImageCache().get(paramString);
		    	if (localBitmap == null){
		    		 String str3 = RemoteImageView.TAG;
		             String str4 = "Trying again to download " + paramString;
		             int i = Log.w(str3, str4);
		             RemoteImageView.this.setImageUrl(paramString);
		    	} else {
		    		
		    	}if (mListView != null)
		    		if(mPosition < mListView.getFirstVisiblePosition() || mPosition > mListView.getLastVisiblePosition())
						return;
		    	RemoteImageView.this.setImageBitmap(localBitmap);
		        mCurrentlyGrabbedUrl = paramString;
		}
		
		//在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
		//@Override
		//protected void onCancelled() {
			//super.onCancelled();
		//}

	};

}
